package com.killer.loader;

import java.io.*;

/**
 * 自定义的类加载器，加载webApp目录下部署的应用的class，同时需要打破双亲委派机制
 */
public class WebAppClassLoader extends ClassLoader{

    //指定类目录
    private String path;

    // 默认会将app类加载器做为该类加载器的父加载器
    public WebAppClassLoader(String path) {
        this.path=path;
    }


    //打破双亲委派机制则不仅要继承ClassLoader类，还要重写loadClass和findClass方法
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        Class<?> clazz = null;
        ClassLoader system = Thread.currentThread().getContextClassLoader();
        try {
            clazz = system.loadClass(name);
        } catch (Exception e) {

        }
        if (clazz != null)
            return clazz;
        clazz = findClass(name);
        return clazz;
    }

    @Override
    public Class<?> findClass(String name) throws ClassNotFoundException {
        // 获取该class文件字节码数组
        byte[] classData = loadBinaryData(name);
        if (classData == null) {
            throw  new ClassNotFoundException();
        }
        return defineClass(name, classData, 0, classData.length);
    }

    public byte[] loadBinaryData(String name) throws ClassNotFoundException{
        File file = new File(path+File.separator + name.replaceAll("\\.", "/") + ".class");
        if(file==null||!file.exists() || !file.isFile()){
            throw  new ClassNotFoundException();
        }
        FileInputStream in = null;
        ByteArrayOutputStream out = null;
        try {
            in = new FileInputStream(file);
            out = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int size = 0;
            while ((size = in.read(buffer)) != -1) {
                out.write(buffer, 0, size);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
        }
        return out.toByteArray();
    }
}
